import datetime
from flask import request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from sqlalchemy import desc, or_
from app.core.extensions import db
from app.models import AdminLog
from app.models.agents import Plan, Order
from . import admin_blueprint
from app.services.decorators import admin_required


@admin_blueprint.route('/plans', methods=['GET', 'OPTIONS'])
@jwt_required(optional=True)
def get_plans():
    """获取套餐列表
    
    查询参数:
    - page: 页码，默认1
    - per_page: 每页数量，默认20
    - search: 搜索关键词（套餐名称）
    - status: 状态筛选（True-启用，False-禁用）
    """
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)
    search = request.args.get('search', '')
    status = request.args.get('status', None)

    # 状态参数处理
    if status is not None:
        if status.lower() == 'true':
            status = True
        elif status.lower() == 'false':
            status = False
        else:
            status = None

    # 构建查询
    query = Plan.query

    # 根据状态筛选
    if status is not None:
        query = query.filter(Plan.status == status)

    # 关键词搜索
    if search:
        query = query.filter(
            or_(
                Plan.name.like(f'%{search}%'),
                Plan.description.like(f'%{search}%')
            )
        )

    # 执行分页查询
    pagination = query.order_by(Plan.sort.desc(), desc(Plan.id)).paginate(
        page=page, per_page=per_page, error_out=False
    )

    plans = pagination.items

    # 构建响应数据
    result = {
        'code': 0,
        'message': '获取成功',
        'data': {
            'total': pagination.total,
            'pages': pagination.pages,
            'page': page,
            'per_page': per_page,
            'items': [plan_to_dict(plan) for plan in plans]
        }
    }

    return jsonify(result)


@admin_blueprint.route('/plans/<int:plan_id>', methods=['GET', 'OPTIONS'])
@jwt_required(optional=True)
def get_plan(plan_id):
    """获取套餐详情"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    plan = Plan.query.get(plan_id)
    if not plan:
        return jsonify({'code': 1, 'message': '套餐不存在'}), 404

    # 获取套餐相关的订单总数
    order_count = Order.query.filter_by(plan_id=plan_id).count()
    paid_order_count = Order.query.filter_by(plan_id=plan_id, status='PAID').count()

    plan_data = plan_to_dict(plan)
    plan_data['stats'] = {
        'order_count': order_count,
        'paid_order_count': paid_order_count
    }

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': plan_data
    })


@admin_blueprint.route('/plans/add', methods=['POST', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def add_plan():
    """添加新套餐"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    data = request.json

    # 提取表单数据
    name = data.get('name')
    amount = data.get('amount')
    times = data.get('times')
    description = data.get('description', '')
    status = data.get('status', True)
    sort = data.get('sort', 0)

    # 验证必要参数
    if not name:
        return jsonify({'code': 1, 'message': '套餐名称不能为空'}), 400

    if amount is None:
        return jsonify({'code': 1, 'message': '套餐价格不能为空'}), 400

    if times is None or times <= 0:
        return jsonify({'code': 1, 'message': '增加使用次数必须大于0'}), 400

    try:
        amount = float(amount)
    except (ValueError, TypeError):
        return jsonify({'code': 1, 'message': '套餐价格必须是数字'}), 400

    # 创建新套餐
    now = datetime.datetime.now()
    plan = Plan(
        name=name,
        amount=amount,
        times=times,
        description=description,
        status=status,
        sort=sort,
        create_time=now,
        update_time=now
    )

    db.session.add(plan)

    # 添加操作日志
    current_user = get_jwt_identity()
    log = AdminLog(
        admin_id=current_user,
        action='添加套餐',
        ip=request.remote_addr,
        details=f'添加套餐 {name}'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '添加成功',
        'data': plan_to_dict(plan)
    })


@admin_blueprint.route('/plans/edit/<int:plan_id>', methods=['POST', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def edit_plan(plan_id):
    """编辑套餐信息"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    plan = Plan.query.get(plan_id)
    if not plan:
        return jsonify({'code': 1, 'message': '套餐不存在'}), 404
    data = request.json

    # 更新套餐信息
    if 'name' in data:
        plan.name = data['name']
    if 'amount' in data:
        try:
            plan.amount = float(data['amount'])
        except (ValueError, TypeError):
            return jsonify({'code': 1, 'message': '套餐价格必须是数字'}), 400
    if 'times' in data:
        plan.times = data['times']
    if 'description' in data:
        plan.description = data['description']
    if 'status' in data:
        plan.status = data['status']
    if 'sort' in data:
        plan.sort = data['sort']

    # 更新更新时间
    plan.update_time = datetime.datetime.now()

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='编辑套餐',
        ip=request.remote_addr,
        details=f'编辑套餐 {plan.name} (ID: {plan.id})'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '更新成功',
        'data': plan_to_dict(plan)
    })


@admin_blueprint.route('/plans/delete/<int:plan_id>', methods=['POST', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def delete_plan(plan_id):
    """删除套餐"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    plan = Plan.query.get(plan_id)
    if not plan:
        return jsonify({'code': 1, 'message': '套餐不存在'}), 404

    # 检查是否有关联的订单
    if Order.query.filter_by(plan_id=plan_id).count() > 0:
        return jsonify({'code': 1, 'message': '该套餐有关联的订单，无法删除'}), 400

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='删除套餐',
        ip=request.remote_addr,
        details=f'删除套餐 {plan.name} (ID: {plan.id})'
    )
    db.session.add(log)

    # 删除套餐
    db.session.delete(plan)
    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '删除成功'
    })


@admin_blueprint.route('/plans/status/<int:plan_id>', methods=['POST', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def update_plan_status(plan_id):
    """更新套餐状态"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    plan = Plan.query.get_or_404(plan_id)
    data = request.json

    if 'status' not in data:
        return jsonify({'code': 1, 'message': '状态参数不能为空'}), 400

    status = data['status']

    # 将状态转换为布尔值
    if isinstance(status, str):
        if status.lower() == 'true':
            status = True
        elif status.lower() == 'false':
            status = False
        else:
            return jsonify({'code': 1, 'message': '状态参数无效'}), 400

    plan.status = status
    plan.update_time = datetime.datetime.now()

    # 添加操作日志
    status_text = '启用' if status else '禁用'
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action=f'{status_text}套餐',
        ip=request.remote_addr,
        details=f'{status_text}套餐 {plan.name} (ID: {plan.id})'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '更新成功',
        'data': plan_to_dict(plan)
    })


@admin_blueprint.route('/plans/sort', methods=['POST', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def sort_plans():
    """批量更新套餐排序"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    data = request.json

    if not isinstance(data, list):
        return jsonify({'code': 1, 'message': '参数格式错误'}), 400

    for item in data:
        plan_id = item.get('id')
        sort = item.get('sort')

        if plan_id and sort is not None:
            plan = Plan.query.get(plan_id)
            if plan:
                plan.sort = sort
                plan.update_time = datetime.datetime.now()

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='更新套餐排序',
        ip=request.remote_addr,
        details='批量更新套餐排序'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '更新成功'
    })


def plan_to_dict(plan):
    """将套餐对象转换为字典"""
    return {
        'id': plan.id,
        'name': plan.name,
        'amount': float(plan.amount),
        'times': plan.times,
        'description': plan.description,
        'status': plan.status,
        'sort': plan.sort,
        'create_time': plan.create_time.strftime('%Y-%m-%d %H:%M:%S') if plan.create_time else None,
        'update_time': plan.update_time.strftime('%Y-%m-%d %H:%M:%S') if plan.update_time else None
    }
